yamlでテストシナリオを書いてそのまま実行までできるAPIテストツールの新星 “runn” を試してみた
これまでのシナリオテストツールに対する課題感
シナリオテストツールといえば、 Cucumber や Gauge といったツールが有名です。
ですが、これらのツールは「シナリオファイル」とは別に、シナリオを実行するためのコードも書かないといけません。しかも、そのコードではAPIを呼び出す処理を特定のプログラミング言語を使って書かなければなりません。その中には、HTTP Clientを実際に操作するような処理も含まれます。
私は「シナリオテストがしたい」のであって、「シナリオに沿ってAPI呼び出しを行う処理を書きたい」のではありません。こういった課題感を、ここ数年ずっと抱えてきました。
そんなとき、ついに見つけたツールが "runn" でした。
APIのシナリオテストに求めるもの
では、シナリオテストツールに求める条件とは何でしょうか?それは端的に言えば
プログラマーでなくても使える
ことではないでしょうか?
テスト設計した人がそのままシナリオを書いてテストを実行する。これができたら最高だと思いませんか?
要素に分解
具体的には、以下のような条件があるとうれしいなと思います。
- シナリオ、テストケースの作りやすさ
- シナリオと同期して具体のテストケースもすぐに直せる
- シナリオ、テストケースの読みやすさ
- シナリオがすっと読み下せる
- その上で、具体で「何を」やっているかもすぐに分かる
- 「どのように」でないのがポイント
- どんな条件で何を期待しているかがわかる *動かしやすさ
- シナリオを書く人が手元でさっと動かせる
- 複雑な環境構築はしたくない
runnなら全部解決できる
そこで、今回取り上げる"runn"です。"runbook"という形式でシナリオを書けば、そのまま実行できるシナリオファイルになります。
このツールであれば、私が求める条件をきれいにクリアできます。
- シナリオ、テストケースの作りやすさ
- シナリオと同期して具体のテストケースもすぐに直せる
- どこに対して何をどうするか書けば良い
- HTTPメソッド
- URL
- パラメータ
- どこに対して何をどうするか書けば良い
- シナリオと同期して具体のテストケースもすぐに直せる
- シナリオ、テストケースの読みやすさ
- シナリオの説明とともに、実際のテストケースがそのまま確認できる
- 複雑な条件なら外部化も可能
- シナリオの説明とともに、実際のテストケースがそのまま確認できる
- 動かしやすさ
- ワンバイナリを置くだけ
- 各種パッケージ管理ツールでの導入もできる
- yamlでシナリオを書いたら後はコマンドを動かすだけ
- ワンバイナリを置くだけ
やってみよう
OAuthで認可を行うAPIに対して、シナリオを作ってテストしてみました。
シナリオでやりたいこと
- OAuth Token Endpoint を実行してアクセストークンを発行
- 発行されたアクセストークンを使ってリソースを登録する
やってみた
テストシナリオは以下のとおりです。コメントで補足しているところといっしょに読んでみてください。
desc: アクセストークンを発行し、テナントを登録する runners: req: http://localhost:8080 steps: createToken: desc: アクセストークンを発行する req: /oauth/token: post: body: application/json: # リクエストパラメータをKey-Value形式で指定する subject: "example" issuer: "http://localhost" expires_in: 86400 test: | # 処理が成功し、JWT形式のアクセストークンが発行されたか検証する current.res.status == 200 && (current.res.body.access_token startsWith "eyJ") == true # 以後のリクエストで使えるよう、発行されたトークンを束縛しておく bind: access_token: current.res.body.access_token bindTenantCode: bind: # UUIDを生成してテナントコードとして使用する tenant_code: faker.UUID() createTenant: desc: テナントを登録する req: /tenants: post: headers: # 発行されたアクセストークンを参照して指定する authorization: "Bearer {{ access_token }}" body: application/json: # bindしたテナントコードを利用する tenant_code: "{{ tenant_code }}" name: "テスト用テナント" title: "テスト用テナントタイトル" test: | # 処理が成功し、指定したのと同じテナントコードでリソースが作成されたか検証する current.res.status == 200 && current.res.body.tenant_code == tenant_code
実行結果は以下のとおりです。--verbose
でなく --debug
オプションを指定すると、実際にAPI呼び出しのリクエスト/レスポンスの内容も確認できます。
$ runn --version runn version 0.99.3 $ runn run scenario.yaml --verbose === アクセストークンを発行し、テナントを登録する (scenario.yaml) --- アクセストークンを発行する (createToken) ... ok --- (bindTenantCode) ... ok --- テナントを登録する (createTenant) ... ok 1 scenario, 0 skipped, 0 failures
世界が変わる
これまでは、シナリオテストといえば「わたしシナリオつくる人、あなたコード書く人」のように役割を分けざるを得ないことが多くありました。しかも、シナリオに対応するテストも、テスターが Postman のようなツールを使って手動で実行するか、シナリオに沿ってAPIを呼び出すテストプログラムをプログラマーが別途書く必要がありました。
しかし、runnのようなツールがあれば、低コストに「動作する受け入れテスト」から始めることができます。ユースケースを元にしたシナリオを作ってシナリオレベルでレビューもできますし、そのシナリオを実行してパスするようにプログラムを書けば、事前に「合意」した仕様を担保できるため、リファクタリングや仕様の変更といった開発サイクルをすばやく回すこともできます。
今後、実際にプロダクト開発で使ってみて、開発プロセス含めて活用方法を考えていきたいと思います。
余談
実は「ツールのコミッターと手軽にコミュニケーションが取れる」ということも、runnの好きなところです。
実際に runnチュートリアル を動かしながら試していたところ、途中でうまく動かない場面に出くわしました。ですが、チュートリアルの著者である @katzchum に雑に X(旧twitter) でメンションしたところ、素早く確認、修正してもらえました。
先日REST APIのシナリオテストツールを探していたところrunnを発見し、
runnチュートリアルhttps://t.co/fuwgYcxkU7
で学んでいる最中です。
(続く— 白い高野さん (@masaru_b_cl) February 23, 2024
また、runnの作者の @k1LoW にも、ロゴをアイキャッチで使用することについて雑メンションしたところ、快く許諾いただきました。
@k1LoW
先日からrunn試させてもらってます。
ブログにしようと思っているのですが、 https://t.co/Z4YNztgny3 のロゴをアイキャッチに使わせていただいてもよろしいでしょうか?— 白い高野さん (@masaru_b_cl) February 26, 2024
今後もぜひ積極的にフィードバックし、何らかの形で貢献し続けられたらと思っています。